#define BLINKER_PRINT Serial
#define BLINKER_MIOT_LIGHT
#define BLINKER_WIFI
// #define Wifi_DIRECT //密码直连取消注释

#include <EEPROM.h>
#define EEPROM_OPERAT_MAX_ADDR              4096    //申请操作到的最大地址addr
#define EEPROM_LAST_R_ADDR                  2432    //颜色亮度储存首地址
#define EEPROM_LAST_G_ADDR                  EEPROM_LAST_R_ADDR+1
#define EEPROM_LAST_B_ADDR                  EEPROM_LAST_G_ADDR+1
#define EEPROM_LAST_BRIGHT_ADDR             EEPROM_LAST_B_ADDR+1
#define EEPROM_COLOR_TEMPERATURE_ADDR       EEPROM_LAST_BRIGHT_ADDR+1
#define EEPROM_RAINBOW_MODE_ADDR            EEPROM_COLOR_TEMPERATURE_ADDR+1
#define EEPROM_BRIGHT_MODE_ADDR             EEPROM_RAINBOW_MODE_ADDR+1

#include <Blinker.h>
#include <Adafruit_NeoPixel.h>

#include <DNSServer.h>//密码直连将其三个库注释
#include <ESP8266WebServer.h>
#include <CustomWiFiManager.h>

// web配网页面自定义我的图标请随便使用一个图片转base64工具转换https://tool.css-js.com/base64.html, 64*64
const char Icon[] PROGMEM = "";

char auth[] = "0782776f6a3f";//app中获取到的Secret Key(密钥)
char ssid[] = "ChinaNet";//wifi名
char pswd[] = "xxxxxx";//wifi密码

int last_r_value=0,last_g_value=0,last_b_value=0,last_bright_value=0;

#define PIN 2   //灯带数据口
#define STATE_LED 2 //状态指示灯
// 灯带 LED 数量
#define NUMPIXELS 18

// 示例：circleLed 数组的定义和初始化
int circleLed[3][6] = {
    {0, 1, 2, 3, 4, 5},
    {6, 7, 8, 9, 10, 11},
    {12, 13, 14, 15, 16, 17}
};

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

unsigned char r=0;unsigned char g=0;unsigned char b=0;
int32_t cct=0; 
int rainbow_mode=0;
int bright_mode=0;
int current_mode=0;

// 新建组件对象
BlinkerRGB RGB1("RGB");
BlinkerSlider Slider1("Sliderkey");
BlinkerButton Button1("btn-0");
BlinkerButton Button2("btn-1");
BlinkerButton Button3("btn-2");
BlinkerButton Button4("btn-3");

BlinkerButton Button5("btn-4");
BlinkerButton Button6("btn-5");

//保存颜色亮度值
void color_bright_save(int addr){

    EEPROM.begin(EEPROM_OPERAT_MAX_ADDR); //申请操作到地址addr
    EEPROM.write(addr,last_r_value);     //给EEPROM 写入值掉电保存   
    EEPROM.write(EEPROM_LAST_G_ADDR,last_g_value);
    EEPROM.write(EEPROM_LAST_B_ADDR,last_b_value);
    EEPROM.write(EEPROM_LAST_BRIGHT_ADDR,last_bright_value);
    EEPROM.commit(); //保存更改的数据
}

//保存色温值
void color_temperature_save(int addr,int32_t value){

    EEPROM.begin(EEPROM_OPERAT_MAX_ADDR); //申请操作到地址addr
    EEPROM.write(addr,value);
    EEPROM.commit(); //保存更改的数据
}

//保存模式
void mode_save(int addr,int r_mode){

    EEPROM.begin(EEPROM_OPERAT_MAX_ADDR); //申请操作到地址addr
    EEPROM.write(addr,r_mode);     //给EEPROM 写入值掉电保存   
    EEPROM.commit(); //保存更改的数据
}

//保存亮度模式
void bright_mode_save(int addr,int b_mode){

    EEPROM.begin(EEPROM_OPERAT_MAX_ADDR); //申请操作到地址addr
    EEPROM.write(addr,b_mode);     //给EEPROM 写入值掉电保存   
    EEPROM.commit(); //保存更改的数据
}

void SET_RGB(int R,int G,int B,int bright){

    //渐变控制算法，颜色亮度变化更加柔和
    while(!( (R == last_r_value) && (G == last_g_value) \
            && (B == last_b_value) && (bright == last_bright_value) )){
        if(R != last_r_value)
            (R > last_r_value)?( ++last_r_value ):( --last_r_value );
        if(G != last_g_value)
            (G > last_g_value)?( ++last_g_value ):( --last_g_value );
        if(B != last_b_value)
            (B > last_b_value)?( ++last_b_value ):( --last_b_value );
        if(bright != last_bright_value)
            (bright > last_bright_value)?( ++last_bright_value ):( --last_bright_value );

        // 把灯条变色
        for (uint16_t i = 0; i < NUMPIXELS; i++)
        {
            pixels.setPixelColor(i,last_r_value,last_g_value,last_b_value);
        }
        // 设置亮度
        pixels.setBrightness(last_bright_value);
        // 送出显示
        pixels.show();
    }
    
    color_bright_save(EEPROM_LAST_R_ADDR);  //保存颜色亮度值
}

// 心跳包函数
void heartbeat() {
    EEPROM.begin(EEPROM_OPERAT_MAX_ADDR); //申请操作到地址EEPROM_OPERAT_MAX_ADDR
    RGB1.print( EEPROM.read(EEPROM_LAST_R_ADDR) , EEPROM.read(EEPROM_LAST_G_ADDR) ,\
        EEPROM.read(EEPROM_LAST_B_ADDR) ,EEPROM.read(EEPROM_LAST_BRIGHT_ADDR));   //上传RGB亮度信息
    Slider1.print(cct);  //发送用户需要的滑动条数值及设置的颜色到APP
}

//APP RGB颜色设置回调
void rgb1_callback(uint8_t r_value, uint8_t g_value, 
                    uint8_t b_value, uint8_t bright_value){

    SET_RGB(r_value,g_value,b_value,bright_value);  
    RGB1.print(last_r_value,last_g_value,last_b_value,last_bright_value);   //上传RGB亮度信息

    BLINKER_LOG("L_R value: ", last_r_value);
    BLINKER_LOG("L_G value: ", last_g_value);
    BLINKER_LOG("L_B value: ", last_b_value);
    BLINKER_LOG("L_Rrightness value: ", last_bright_value); 

    rainbow_mode = 0;
    mode_save(EEPROM_RAINBOW_MODE_ADDR,rainbow_mode);
    bright_mode = 0;
    bright_mode_save(EEPROM_BRIGHT_MODE_ADDR,bright_mode);
    current_mode = 0;
}

//********模拟旋转****
// 定义暖黄色
#define WARM_YELLOW_R 255
#define WARM_YELLOW_G 140
#define WARM_YELLOW_B 0

// 设置LED颜色的函数，包括亮度
void setPixelColorWithBrightness(int pixelIndex, uint8_t r, uint8_t g, uint8_t b, uint8_t brightness) {
  uint8_t actualR = (r * brightness) / 255;
  uint8_t actualG = (g * brightness) / 255;
  uint8_t actualB = (b * brightness) / 255;
  pixels.setPixelColor(pixelIndex, actualR, actualG, actualB);
}

// 初始化所有LED熄灭
void initializeAllLEDsOff() {
  for (int i = 0; i < NUMPIXELS; i++) {
    pixels.setPixelColor(i, 0);  // 设置每个LED的颜色为黑色（熄灭）
  }
  pixels.show();  // 更新LED状态，确保所有LED熄灭
}

void cycleColumns() {
    static int column = 0;         // 当前点亮的列索引
    static int brightness = 0;     // 当前列的亮度
    static bool increasing = true; // 当前亮度是否在增加

    // 初始化所有LED熄灭
//    +
    
    // 遍历每一行的LED，更新当前列的亮度
    for (int row = 0; row < 3; row++) {
        int lightPixelIndex = circleLed[row][column];                    // 当前列的像素索引
        int downPixelIndex = circleLed[row][(column - 1 + 6) % 6];      // 前一列的像素索引

        // 设置当前列的亮度
        setPixelColorWithBrightness(lightPixelIndex, WARM_YELLOW_R, WARM_YELLOW_G, WARM_YELLOW_B, brightness);

        // 如果前一列的亮度不为0，设置前一列的亮度
        int previousBrightness = (brightness == 0) ? 0 : 120 - brightness;
        setPixelColorWithBrightness(downPixelIndex, WARM_YELLOW_R, WARM_YELLOW_G, WARM_YELLOW_B, previousBrightness);
    }

    // 逐步调整亮度，减小变化的步长
    if (increasing) {
        brightness += 10; // 增加亮度（减小步长）
        if (brightness >= 120) {
            brightness = 120;
            increasing = false; // 开始减少亮度
        }
    } else {
        brightness -= 10; // 减少亮度（减小步长）
        if (brightness <= 0) {
            brightness = 0;
            increasing = true;            // 切换到增加亮度
            column = (column + 1) % 6;    // 切换到下一列
        }
    }

    pixels.show(); // 更新LED状态
    delay(30);     // 控制亮度变化速度，减缓更新频率
}

//***********

//***模拟蜡烛***
// 定义暖黄色
void candleEffect() {
  static unsigned long previousMillis = 0;  // 用于记录上次更新时间
  unsigned long currentMillis = millis();   // 获取当前时间

  // 蜡烛火焰效果的时间间隔
  static unsigned long interval = random(50, 150);  // 随机延迟，模拟火焰不规则闪烁

  // 如果经过了时间间隔才更新效果
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;  // 重新计时
    interval = random(50, 150);      // 随机延迟

    // 遍历每一列和每一行的LED
    for (int column = 0; column < 6; column++) {  // 遍历每一列
      for (int row = 0; row < 3; row++) {         // 遍历每一行
        int pixelIndex = circleLed[row][column];  // 当前像素索引

        // 生成随机亮度，模拟火焰波动（80到255之间随机波动）
        int brightness = random(20, 160);

        // 增加颜色偏差，模拟火焰颜色变化
        int flickerR = WARM_YELLOW_R - random(0, 30);
        int flickerG = WARM_YELLOW_G - random(0, 20);
        int flickerB = WARM_YELLOW_B;

        // 设置LED颜色和亮度
        setPixelColorWithBrightness(pixelIndex, flickerR, flickerG, flickerB, brightness);
      }
    }

    pixels.show();  // 更新LED状态
  }
}

//************



//*******呼吸灯效果*********
void randomColorBreathingEffect() {
    static bool isBreathingUp = true; // 用于记录当前是增亮还是减弱
    static int brightness = 0;       // 记录当前亮度

    // 每次进入函数更新一个呼吸变化
    if (isBreathingUp) {
        brightness += 5; // 增亮
        if (brightness >= 255) {
            brightness = 255;
            isBreathingUp = false; // 切换到减弱
        }
    } else {
        brightness -= 5; // 减弱
        if (brightness <= 0) {
            brightness = 0;
            isBreathingUp = true; // 切换到增亮
        }
    }

    // 随机颜色生成
    int r = random(0, 256);
    int g = random(0, 256);
    int b = random(0, 256);

    // 更新所有 LED 的颜色和亮度
    for (int i = 0; i < NUMPIXELS; i++) {
        setPixelColorWithBrightness(i, r, g, b, brightness);
    }
    pixels.show();

    delay(100); // 控制呼吸速度
}

//**********************

//APP 滑动条设置回调
void slider1_callback(int32_t value){

    // BLINKER_LOG("get slider value: ", value);
    EEPROM.begin(EEPROM_OPERAT_MAX_ADDR); //申请操作到地址EEPROM_OPERAT_MAX_ADDR
    Color_temperature_conversion(value,&r,&g,&b);   //色温转RGB
    SET_RGB( r , g , b , EEPROM.read(EEPROM_LAST_BRIGHT_ADDR) );  

    // color_temperature_save(EEPROM_COLOR_TEMPERATURE_ADDR,value);    //保存色温值
    RGB1.print(last_r_value,last_g_value,last_b_value,last_bright_value);   //上传RGB亮度信息
    cct = value;
    Slider1.print(cct);  //发送用户需要的滑动条数值及设置的颜色到APP

    rainbow_mode = 0;
    mode_save(EEPROM_RAINBOW_MODE_ADDR,rainbow_mode);
    bright_mode = 0;
    bright_mode_save(EEPROM_BRIGHT_MODE_ADDR,bright_mode);
    current_mode = 0;
}

//APP 按键设置回调
void button1_callback(const String & state)
{
    BLINKER_LOG("get button state: DAY");
    if(state == "pressup"){
        return;
    }
    else if(state == "on"){
        bright_mode = 0;
    }
    else{
        bright_mode = 1;
    }
    EEPROM.begin(EEPROM_OPERAT_MAX_ADDR); //申请操作到地址EEPROM_OPERAT_MAX_ADDR
    SET_RGB(255,67,1, EEPROM.read(EEPROM_LAST_BRIGHT_ADDR));  
    SET_RGB(255,67,0, EEPROM.read(EEPROM_LAST_BRIGHT_ADDR));  
    rainbow_mode = 0;
    mode_save(EEPROM_RAINBOW_MODE_ADDR,rainbow_mode);
    bright_mode_save(EEPROM_BRIGHT_MODE_ADDR,bright_mode);
    current_mode = 0;
}
void button2_callback(const String & state)
{
    BLINKER_LOG("get button state: NIGHT");
    if(state == "pressup"){
        return;
    }
    else if(state == "on"){
        bright_mode = 0;
    }
    else{
        bright_mode = 1;
    }
    EEPROM.begin(EEPROM_OPERAT_MAX_ADDR); //申请操作到地址EEPROM_OPERAT_MAX_ADDR
    SET_RGB(201,218,254, EEPROM.read(EEPROM_LAST_BRIGHT_ADDR) );  
    SET_RGB(201,218,255, EEPROM.read(EEPROM_LAST_BRIGHT_ADDR) );  
    rainbow_mode = 0;
    mode_save(EEPROM_RAINBOW_MODE_ADDR,rainbow_mode);
    bright_mode_save(EEPROM_BRIGHT_MODE_ADDR,bright_mode);
    current_mode = 0;
}
void button3_callback(const String & state)
{
    BLINKER_LOG("get button state: COMPUTER");
    rainbow_mode = 1;
    mode_save(EEPROM_RAINBOW_MODE_ADDR,rainbow_mode);
    bright_mode = 0;
    bright_mode_save(EEPROM_BRIGHT_MODE_ADDR,bright_mode);
    current_mode = 0;
}
void button4_callback(const String & state)
{
    EEPROM.begin(EEPROM_OPERAT_MAX_ADDR); //申请操作到地址EEPROM_OPERAT_MAX_ADDR
    SET_RGB(255,0,87, EEPROM.read(EEPROM_LAST_BRIGHT_ADDR) );
    SET_RGB(255,0,88, EEPROM.read(EEPROM_LAST_BRIGHT_ADDR) );  
    rainbow_mode = 0;
    mode_save(EEPROM_RAINBOW_MODE_ADDR,rainbow_mode);
    bright_mode = 0;
    bright_mode_save(EEPROM_BRIGHT_MODE_ADDR,bright_mode);
    current_mode = 0;
}

void button5_callback(const String & state)
{
     BLINKER_LOG("get button state: RANDOM COLOR BREATHING");
    
    // 如果是 "pressup" 操作，直接返回
    if (state == "pressup") {
        return;
    }
    rainbow_mode = 0;
    mode_save(EEPROM_RAINBOW_MODE_ADDR,rainbow_mode);
    bright_mode = 0;
    bright_mode_save(EEPROM_BRIGHT_MODE_ADDR,bright_mode);
    
    current_mode = 5; // 设置当前模式为随机颜色呼吸效果
}
void button6_callback(const String &state) {
    BLINKER_LOG("get button state: CYCLE COLUMNS");

    // 如果是 "pressup" 操作，直接返回
    if (state == "pressup") {
        return;
    }

    // 切换到循环列模式
    rainbow_mode = 0;
    mode_save(EEPROM_RAINBOW_MODE_ADDR, rainbow_mode); // 关闭彩虹模式

    bright_mode = 0;
    bright_mode_save(EEPROM_BRIGHT_MODE_ADDR, bright_mode); // 关闭亮度模式

    current_mode = 4; // 设置当前模式为循环列模式
    
}

//小爱设置颜色回调
void miotColor(int32_t color){
    uint8_t colorR;uint8_t colorG;uint8_t colorB;

    BLINKER_LOG("need set color: ", color);
    colorR = color >> 16 & 0xFF;
    colorG = color >>  8 & 0xFF;
    colorB = color       & 0xFF;

    EEPROM.begin(EEPROM_OPERAT_MAX_ADDR); //申请操作到地址addr
    SET_RGB( colorR , colorG , colorB , EEPROM.read(EEPROM_LAST_BRIGHT_ADDR) );  

    BLINKER_LOG("colorR: ", colorR, ", colorG: ", colorG, ", colorB: ", colorB);

    BlinkerMIOT.color(color);
    BlinkerMIOT.print();    //属性发送出去

    rainbow_mode = 0;
    mode_save(EEPROM_RAINBOW_MODE_ADDR,rainbow_mode);
    bright_mode = 0;
    bright_mode_save(EEPROM_BRIGHT_MODE_ADDR,bright_mode);
}

//小爱设置色温回调
void miotColoTemp(int32_t colorTemp)
{
    slider1_callback(colorTemp);

    BlinkerMIOT.colorTemp(colorTemp);
    BlinkerMIOT.print();
}

//小爱设置模式回调
void miotMode(uint8_t mode)
{
    BLINKER_LOG("need set mode: ", mode);
      //日光模式
    if (mode == BLINKER_CMD_MIOT_DAY) {    
        button1_callback("on");
    }
    //月光模式
    else if (mode == BLINKER_CMD_MIOT_NIGHT) {
        button2_callback("on");
    }
    //彩光模式
    else if (mode == BLINKER_CMD_MIOT_COLOR) {
        button4_callback("on");
    }
    //温馨模式
    else if (mode == BLINKER_CMD_MIOT_WARMTH) {
        //button5_callback("on");
        // Your mode function
    }
    //电视模式
    else if (mode == BLINKER_CMD_MIOT_TV) {
        // Your mode function
    }
    //阅读模式
    else if (mode == BLINKER_CMD_MIOT_READING) {
        // Your mode function
    }
    //电脑模式
    else if (mode == BLINKER_CMD_MIOT_COMPUTER) {
        button3_callback("on");
    }

    BlinkerMIOT.mode(mode);
    BlinkerMIOT.print();
}

//小爱电源回调
void miotPowerState(const String & state)
{
    BLINKER_LOG("need set power state: ", state);

    if (state == BLINKER_CMD_ON) {
        EEPROM.begin(EEPROM_OPERAT_MAX_ADDR); //申请操作到地址EEPROM_OPERAT_MAX_ADDR
        SET_RGB( EEPROM.read(EEPROM_LAST_R_ADDR) , EEPROM.read(EEPROM_LAST_G_ADDR) ,\
            EEPROM.read(EEPROM_LAST_B_ADDR) , 155 );
        rainbow_mode = EEPROM.read(EEPROM_RAINBOW_MODE_ADDR);    
        bright_mode = EEPROM.read(EEPROM_BRIGHT_MODE_ADDR);

        BlinkerMIOT.powerState("on");
    }
    else if (state == BLINKER_CMD_OFF) {
        EEPROM.begin(EEPROM_OPERAT_MAX_ADDR); //申请操作到地址EEPROM_OPERAT_MAX_ADDR
        SET_RGB( EEPROM.read(EEPROM_LAST_R_ADDR) , EEPROM.read(EEPROM_LAST_G_ADDR) ,\
            EEPROM.read(EEPROM_LAST_B_ADDR) , 0 );
        rainbow_mode = 0;
        bright_mode = 0;

        BlinkerMIOT.powerState("off");
    }
    BlinkerMIOT.print();
}

void setup() {
    // 初始化串口
    Serial.begin(115200);
    Serial.println();

    // WS2812初始化
    pixels.begin();
    // pixels.show();
    pinMode(PIN, OUTPUT);
    pinMode(STATE_LED, OUTPUT);
    digitalWrite(STATE_LED, LOW);   //打开WIFI指示灯

    EEPROM.begin(EEPROM_OPERAT_MAX_ADDR); //申请操作到地址EEPROM_OPERAT_MAX_ADDR
    SET_RGB( EEPROM.read(EEPROM_LAST_R_ADDR) , EEPROM.read(EEPROM_LAST_G_ADDR) ,\
        EEPROM.read(EEPROM_LAST_B_ADDR) ,EEPROM.read(EEPROM_LAST_BRIGHT_ADDR));
    rainbow_mode = EEPROM.read(EEPROM_RAINBOW_MODE_ADDR);    
    bright_mode = EEPROM.read(EEPROM_BRIGHT_MODE_ADDR);

    //打开blinker调试
    #if defined(BLINKER_PRINT)
        BLINKER_DEBUG.stream(BLINKER_PRINT);
    #endif

    #if defined(Wifi_DIRECT)    //WIFI直连
        Blinker.begin(auth,ssid,pswd);
    #else
        //Web配网
        webconnect();
        // 初始化blinker
        Blinker.begin(auth, WiFi.SSID().c_str(), WiFi.psk().c_str());
    #endif
    digitalWrite(STATE_LED, HIGH);  ///连接成功,关闭WIFI指示灯

    // 注册调节颜色的回调函数
    RGB1.attach(rgb1_callback);
    // 注册滑动条的回调函数
    Slider1.attach(slider1_callback);
    // 注册按键的回调函数
    Button1.attach(button1_callback);
    Button2.attach(button2_callback);
    Button3.attach(button3_callback);
    Button4.attach(button4_callback);
    Button5.attach(button5_callback);
    Button6.attach(button6_callback);
    // 注册心跳包函数
    Blinker.attachHeartbeat(heartbeat);
    // 注册小爱设置颜色函数
    BlinkerMIOT.attachColor(miotColor);
    // 注册小爱设置色温函数
    BlinkerMIOT.attachColorTemperature(miotColoTemp);
    // 注册小爱设置模式函数
    BlinkerMIOT.attachMode(miotMode);
    // 注册小爱电源函数
    BlinkerMIOT.attachPowerState(miotPowerState);
}

void loop() {
    Blinker.run();
    if(rainbow_mode == 1){
        rainbow(1);
    }
    if(bright_mode == 1){
        bright_mode_set(1);
    }
    if (current_mode == 4) {
        cycleColumns(); 
    }
    if (current_mode == 5) {
        candleEffect(); 
    }
}

//Web配网
void webconnect() {  

  WiFiManager wifiManager;  //实例化WiFiManager
  wifiManager.setDebugOutput(true); //打开Debug
  //wifiManager.setConnectTimeout(10); //设置超时
  wifiManager.setHeadImgBase64(FPSTR(Icon)); //设置图标
  wifiManager.setPageTitle("WiFi配置页");  //设置页标题

  if (!wifiManager.autoConnect("RGB_light")) {  //AP模式
    Serial.println("连接失败并超时");
    //重新设置并再试一次，或者让它进入深度睡眠状态
    ESP.restart();
    delay(1000);
  }
  digitalWrite(STATE_LED, HIGH);
  Serial.println("connected...^_^");
  yield();
}

/*******************************************************************************
*@ Description    将RGB转换成色温（CCT）  
*@ Input          :<tmpKelvin>输入的色温值（[1000,40000]单位：K，开尔文）
*@ Output         :
*@ Return         :
*******************************************************************************/
int Color_temperature_conversion(unsigned int tmpKelvin,unsigned char* r,unsigned char* g,unsigned char* b){
 
    static double tmpCalc = 0;
    
    if(tmpKelvin < 1000){
        tmpKelvin = 1000;
    }
    if(tmpKelvin > 40000){
        tmpKelvin = 40000;
    }
    tmpKelvin = tmpKelvin/100;
    
    /*----#red----------------------------------------------------------------------------*/
    if(tmpKelvin <= 66){
        *r = 255;
    }
    else{
        tmpCalc = tmpKelvin - 60;
        tmpCalc = 329.698727446 * (pow(tmpCalc,-0.1332047592));
        *r = tmpCalc;
        if(*r <0){
            *r = 0;
        }
    
        if(*r > 255){
            *r = 255;
        }
    }
    
    /*----#green----------------------------------------------------------------------------*/
    if(tmpKelvin <= 66){
        tmpCalc = tmpKelvin;
        tmpCalc = 99.4708025861 * log(tmpCalc) - 161.1195681661;
        *g = tmpCalc;
    
        if(*g < 0){
            *g = 0;
        }
        if(*g > 255){
            *g = 255;
        }    
    }
    else{
        tmpCalc = tmpKelvin - 60;
        tmpCalc = 288.1221695283 * (pow(tmpCalc,-0.0755148492));
        *g = tmpCalc;
    
        if(*g < 0){
            *g = 0;
        }
        if(*g > 255){
            *g = 255;
        }    
    }
    
    /*----#blue----------------------------------------------------------------------------*/
    if(tmpKelvin >= 66){
        *b = 255;
    }
    else if(tmpKelvin <= 19){
        *b = 0;
    }
    else{
        tmpCalc = tmpKelvin - 10; 
        tmpCalc = 138.5177312231 * log(tmpCalc) - 305.0447927307;
        *b = tmpCalc;
    
        if(*b < 0){
            *b = 0;
        }
        if(*b > 255){
            *b = 255;
        }
    }
    return 0;
}

// 彩虹沿整条循环,通过帧之间的延迟时间(毫秒) 
void rainbow(int wait) {
  for(long firstPixelHue = 0; (firstPixelHue < 5*65536) && (rainbow_mode == 1); firstPixelHue += 256) {
    for(int i=0; (i<pixels.numPixels()) && (rainbow_mode == 1); i++) { 
      int pixelHue = firstPixelHue + (i * 65536L / pixels.numPixels());
      pixels.setPixelColor(i, pixels.gamma32(pixels.ColorHSV(pixelHue)));
    //   Blinker.run();
    }
    pixels.show(); // 送出显示
    Blinker.run();
    delay(wait);  // 延时等待
  }
}

void bright_mode_set(int ms){
    for(int b=0; (b<255) && (bright_mode == 1) ; b+=3){
        // 把灯条变色
        for (uint16_t i = 0; i < NUMPIXELS; i++)
        {
            pixels.setPixelColor(i,last_r_value,last_g_value,last_b_value);
        }
        // 设置亮度
        pixels.setBrightness(b);
        // 送出显示
        pixels.show();
        Blinker.run();
        // delay(ms);
    }
    for(int b=255; (b>0) && (bright_mode == 1) ; b-=3){
        // 把灯条变色
        for (uint16_t i = 0; i < NUMPIXELS; i++)
        {
            pixels.setPixelColor(i,last_r_value,last_g_value,last_b_value);
        }
        // 设置亮度
        pixels.setBrightness(b);
        // 送出显示
        pixels.show();
        Blinker.run();
        // delay(ms);
    }
}
